﻿using System;
using System.Activities;
using System.Activities.Tracking;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
using System.Threading.Tasks;
using SLS.DataBase;
using SLS.ExClassLib.Data;
using SLS.ExClassLib.Database;
using SLS.ExClassLib.Events;
using SLS.ExClassLib.Message;
using SLS.ExClassLib.WFActivities;
using SLS.ExClassLib.Loc.Attributes;
namespace SLS.ExClassLib.MVVM
{ 
    /// <summary>
    /// The atm wpf view model.
    /// </summary>
    public partial class DataModel : TraceListener, IDataModel, INotifyPropertyChanged
    {
        public Dictionary<string, object> SetUpdoc = new Dictionary<string, object>();
        public DataTable tableGoodsTypeKeyDef
        {
            get
            {
                return DataAccessService.Instance.GlobalDataSet.GTDEF;
            }
        }
        public DataTable tableGoodsType
        {
            get
            {
                return DataAccessService.Instance.GlobalDataSet.GOODSTYPE;
            }
        }
        public DataTable TBForeignKeyList
        {
            get
            {
                return DataAccessService.Instance.GlobalDataSet.FOREIGNKEYLIST;
            }
        }
        public DataTable TBGoodsTypeKeyDefRelation
        {
            get
            {
                return DataAccessService.Instance.GlobalDataSet.GTKR;
            }
        }
        public SLDBSET SetGlobal
        {
            get
            {
                return DataAccessService.Instance.GlobalDataSet;
            }
        }
        public SLQDBSET SetQuery
        {
            get
            {
                return DataAccessService.Instance.setQueryCond;
            }
        }
        public SLDBSET GlobalDataSet
        {
            get
            {
                return DataAccessService.Instance.GlobalDataSet;
            }
        }

        public DataModel()
        { 
        }
        public DataModel(string basetable)
        {
            this.BaseTable = basetable;
        }
        #region Constants and Fields 
        /// <summary>
        ///   Task for closing the workflow when the UI shuts down
        /// </summary>
        private Task closingTask; 
        #endregion 

        #region Events

        /// <summary>
        ///   The property changed.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
                /// <summary>
        /// Publishes the PropertyChanged event.
        /// </summary>
        /// <param name="propertyName"></param>
        [OnPropertyChangeMethod("propertyName")]
        public void OnPropertyChange(String propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

        #region Properties
        public string BaseTable { get; set; }
        //sun20121002
        /*
        SLBC m_ExEDIT;
        public SLBC ExEDIT
        {
            get { return m_ExEDIT; }
            set 
            {
                m_ExEDIT = value; 
                SetUpdoc = m_ExEDIT.SetUpdoc;
                HostAddress = m_ExEDIT.Address;
                IsLoadSet2Create = m_ExEDIT.flageLoadSet2Create;
                IsLoadSet4Reference = m_ExEDIT.flagLoadSet4Reference;
                IsLoadSet5KeyDef = m_ExEDIT.flagLoadSet5KeyDef;
                BaseTable = m_ExEDIT.BaseTable; 
            }
        }*/
        private Queue m_TmpJobQ = null;
        public Queue TmpJobQ
        {
            get
            {
                if (m_TmpJobQ == null)
                    m_TmpJobQ = new Queue();
                return m_TmpJobQ;
            }
            set
            {
                m_TmpJobQ = value;
            }
        }
        DataTable TableBase
        {
            get
            {
                return SetEnv.Tables[BaseTable];
            }
        }
        private SLQDBSET m_SetUQ = null;
        public SLQDBSET SetUQ 
        {
            get
            {
                if (m_SetUQ == null)
                     m_SetUQ=new SLQDBSET();
                return m_SetUQ;
            }
            set
            {
                m_SetUQ = value;
            }
        } 
        private SLDBSET m_SetUI = null;
        public SLDBSET SetUI
        {
            get
            {
                if (m_SetUI == null)
                    m_SetUI = new SLDBSET();
                return m_SetUI;
            }
            set
            {
                m_SetUI = value;
            }
        }
        private SLDBSET m_SetEnv = null;
        public SLDBSET SetEnv
        {
            get
            {
                if (m_SetEnv == null)
                    m_SetEnv = new SLDBSET();
                return m_SetEnv;
            }
            set
            {
                m_SetEnv = value;
            }
        }
        public WFMachine WFMachine { get; set; }
        /// <summary>
        ///   The atm machine.
        /// </summary>
        public Activity WFActivity
        {
            get;
            set;
        }
        public string HostAddress
        {
            get;
            set;
        }
        public bool IsLoadSet5KeyDef
        {
            get;
            set;
        }
        public bool IsLoadSet4Reference
        {
            get;
            set;
        }
        public bool IsLoadSet2Create
        {
            get;
            set;
        }
        public bool IsCheckDataQuality { get; set; }
        /// <summary>
        ///   Gets MachineJoinCommand.
        /// </summary>
        public ICommand MachineJoinCommand { get; private set; }


        /// <summary>
        ///   Gets the PowerOff command
        /// </summary>
        public ICommand PowerOffCommand { get; set; }

        /// <summary>
        ///   Gets the PowerOn command
        /// </summary>
        public ICommand PowerOnCommand { get; set; }

        /// <summary>
        ///   Gets RemoveCardCommand.
        /// </summary>
        public ICommand RemoveCardCommand { get; set; }

        /// <summary>
        ///   Gets or sets SideButtonCommand.
        /// </summary>
        public ICommand SideButtonCommand { get; set; }

        /// <summary>
        ///   Assign a new job
        /// </summary>
        public ICommand AssignNewJobCommand { get; set; }

        /// <summary>
        ///   Assign a new job
        /// </summary>
        public ICommand QualityCheckCommand { get; set; }

        /// <summary>
        ///   Gets TrackingParticipant.
        /// </summary>
        public TrackingParticipant TrackingParticipant
        {
            get
            {
                return null;
            }
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// The view closed.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The event args.
        /// </param>
        public void ViewClosed(object sender, EventArgs e)
        {
            // TODO
            if (this.closingTask != null)
            {
                this.closingTask.Wait();
            }
        }

        /// <summary>
        /// The view closing.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The event args.
        /// </param>
        public void ViewClosing(object sender, CancelEventArgs e)
        {
            // TODO
            if (this.WFMachine != null)
            {
                this.closingTask = this.WFMachine.TurnPowerOff();
            }
        }

        #endregion

        #region Implemented Interfaces

        #region IDataModel 
        public void LoadForeignKeyTable(ExDataRow dwThis)
        { 
            try
            { 
                if (dwThis == null)
                    return;
                Clear();
                dwThis.LoadLifeData(1);  
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
        }
        public bool ValidateJob(ExDataRow job)
        {
            bool IsValidate = true;
            try
            {
                if (job == null)
                    return false;
                string STATUS = job.STATUS;
                if (STATUS.Contains("OnLoadingForeignKeyTable;"))
                    IsValidate = false;
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
            return IsValidate;
        }
        public bool ValidateForeignKey(ExDataRow job, string foreignkey)
        {
            bool IsValidate = false;
            try
            {
                IsValidate = true;
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
            return IsValidate;
        }

        /// <summary>
        /// The clear.
        /// </summary>
        public void Clear()
        {
            Tracer.Info("WFMViewModel", "View Clear");
        }

        /// <summary>
        /// The display DisplayRow1.
        /// </summary>
        /// <param name="prompt">
        /// The prompt.
        /// </param>
        public void Prompt(WFPrompt prompt)
        {
            if (prompt.PType == "WFState")
            {
                this.WFMachine.CurrentState = prompt.Text;
            }
            Tracer.Info(this.HostAddress, prompt.ToString()); 
        }

        /// <summary>
        /// The model has notified that a command should be enabled
        /// </summary>
        /// <param name="transition">
        /// The command.
        /// </param>
        public void EnableTransition(MachineTransition transition)
        {
            RequeryCommands();
        }

        /// <summary>
        /// The notify.
        /// </summary>
        /// <param name="transition">
        /// The atm notification.
        /// </param>
        /// <param name="payload">
        /// The transition payload
        /// </param>
        public void Notify(MachineTransition transition, object payload)
        {
            Tracer.Info("WFMViewModel", transition.ToString());
        }

        /// <summary>
        /// The notify.
        /// </summary>
        /// <param name="readerResult">
        /// The reader result.
        /// </param>
        public void Notify(BaseEvent readerResult)
        {
            Tracer.Info(this.WFActivity.ToString() + " Address:" + WFActivity.Id.ToString(), readerResult.ToString());
        }

        /// <summary>
        /// The state changed.
        /// </summary>
        /// <param name="state">
        /// The state.
        /// </param>
        public void StateChanged(string state)
        {
            Tracer.Info("WFMViewModel", state.ToString());
            RequeryCommands();
        }

        public void InputJobPool(MessageEx msg)
        {
            try
            {
                this.WFMachine.InputJobPool(msg);
                this.NotifyChanged("InputJobPool");
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
        }
        public void OutputJobPool(MessageEx msg)
        {
            try
            {
                this.WFMachine.OutJobPool(msg);
                this.NotifyChanged("InputJobPool");
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
        }
        public ExDataRow GetJob()
        {
            ExDataRow job = null;
            MessageEx msg;
            try
            {
                if (TmpJobQ.Count > 0)
                {
                    job = (ExDataRow)TmpJobQ.Dequeue();
                    return job;
                }
                msg = this.WFMachine.GetJob(); 
                foreach (DataRow dwEvent in msg.setEvent.Tables[0].Rows)
                {
                    ExDataRow exd = new ExDataRow();
                    job = exd.GetExDataRow(dwEvent, true);
                    TmpJobQ.Enqueue(job);
                }
                if (TmpJobQ.Count > 0)
                {
                    job = (ExDataRow)TmpJobQ.Dequeue();
                }
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
            return job;
        }

        public bool CheckNewJob()
        {
            return this.WFMachine.CheckNewJob();
        }

        #endregion

        #endregion 
    }
}